#ifndef _META_QUEUE_
#define _META_QUEUE_

#include <queue>
#include "mutex.h"

template< typename Meta >
class MetaQueue
{
public:
	typedef Guard<Thread_Mutex>		QueueGuard;

	MetaQueue() {}

	~MetaQueue() throw() {}

	int32_t empty() const
	{
		QueueGuard guard( m_mutex );
		return m_queue.empty();
	}

	uint32_t size() const
	{
		QueueGuard guard( m_mutex );
		return m_queue.size();
	}

	int32_t enqueue( Meta meta )
	{
		QueueGuard guard( m_mutex );
        //debug_output( "enqueue meta count(%lu)", m_queue.size() );
		m_queue.push( meta );
		m_mutex.notify();
        return 0;
	}

    int32_t dequeue( Meta & meta )
	{
		QueueGuard guard( m_mutex );

		if( !m_queue.empty() )
		{
			meta = m_queue.front();
			m_queue.pop();
            return 0;
            //debug_output( "dequeue meta count(%lu)", m_queue.size() );
		}
		return -1;
	}

	Meta dequeue_wait()
	{
		QueueGuard guard( m_mutex );

		Meta meta;
        memset( &meta, 0, sizeof( meta ) );
		if( !m_queue.empty() )
		{
			meta = m_queue.front();
			m_queue.pop_front();
		}
		else
		{
			while( m_queue.empty() )
			{
				m_mutex.wait();
			}
			m_mutex.acquire();
			meta = m_queue.front();
			m_queue.pop_front();
		}
		return meta;
	}

private:
	std::queue<Meta>	    m_queue;
	mutable Thread_Mutex	m_mutex;

private:
	MetaQueue( const MetaQueue & );
	const MetaQueue operator= ( const MetaQueue & );
};

#endif // _META_QUEUE_


